package com.wxproject.demo.Controller.FaceCheck;

import com.google.gson.Gson;
import com.wxproject.demo.Common.MyException.BusinessException;
import com.wxproject.demo.Common.exception.ResultEnum;
import com.wxproject.demo.Common.lang.ResultBody;
import com.wxproject.demo.Entity.Bean.FaceBean.*;
import com.wxproject.demo.Service.FackCheckService.DBFactory;
import com.wxproject.demo.Service.FackCheckService.FaceH5Check;
import com.wxproject.demo.Service.FackCheckService.FaceOperate;
import com.wxproject.demo.Service.LoginService;
import com.wxproject.demo.Utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author zqf
 * @date 2021/4/2 12:26
 * @description
 */
@RestController
@RequestMapping("/faceCheck")
public class FaceCheckController {
    @Autowired
    private LoginService loginService;


    //注册人脸信息(必须先登录才能注册人脸信息)
    @PostMapping("/faceRegister")
    public ResultBody addFace(HttpServletRequest rq, @RequestParam("faceUrl") String faceUrl) {
        String userId = JWTUtil.getUserId(rq.getHeader("Token"));
        String username = JWTUtil.getUsername(rq.getHeader("Token"));
        String faceUserInfo = FaceOperate.userGet(userId);
        FaceUserBean faceUserBean = new Gson().fromJson(faceUserInfo, FaceUserBean.class);
        if (faceUserBean.getError_code() == 223103) {
            FaceOperate.add(userId, "user", faceUrl, username);
            return ResultBody.ok().message("注册成功");
        }
        return ResultBody.ok().message("人脸已存在");
    }

    //修改人脸信息(必须先登录才能修改人脸信息)
    //更新将覆盖所有人脸信息
    @PostMapping("/updateFace")
    public ResultBody updateFace(HttpServletRequest rq, @RequestParam("faceUrl") String faceUrl) {
        String userId = JWTUtil.getUserId(rq.getHeader("Token"));
        String username = JWTUtil.getUsername(rq.getHeader("Token"));
        String json = FaceOperate.faceUpdate(faceUrl, userId, username);
        FaceResultBean faceResultBean = new Gson().fromJson(json, FaceResultBean.class);
        if (faceResultBean.getResult() == null) {
            return ResultBody.error().message(faceResultBean.getError_msg());
        }
        return ResultBody.ok().message("更新成功");
    }


    //通过图片登陆
    //搜索人脸信息
    @PostMapping("/faceLogin")
    public ResultBody addSearch(@RequestParam("file") MultipartFile file) throws Exception {
        ResultBody result = UploadUtil.uploadFileReturnUrl(file);
        String faceUrl = result.getData().get("url").toString();
        String json = FaceOperate.faceSearchByUrl(faceUrl, "user");
        System.out.println(json);
        FaceResultBean faceResultBean = new Gson().fromJson(json, FaceResultBean.class);
        String jsons = FaceOperate.faceVerify(faceUrl);
        FaceLiveBean faceLiveBean = new Gson().fromJson(jsons, FaceLiveBean.class);
        try {
            double faceLiveScore = faceLiveBean.getResult().getFace_liveness();
            //获得表情
            String express = faceLiveBean.getResult().getFace_list().get(0).getExpression().getType();
            //活体认证
            System.out.println("faceLiveScore===="+faceLiveScore);
            double score = faceResultBean.getResult().getUser_list().get(0).getScore();
            if (faceLiveScore < 0.8) {
                return ResultBody.error().message("请对准屏幕");
            }
//            if (!express.equals("smile")){
//                return ResultBody.error().message("请微笑并重试");
//            }
            if (faceResultBean.getError_code() == 223120) {
                return ResultBody.error().message("无法识别");
            }
            String jwtId = UUID.randomUUID().toString();
            System.out.println("score:"+score);
            if (score >= 80) {
                String userId = faceResultBean.getResult().getUser_list().get(0).getUser_id();
                String username = faceResultBean.getResult().getUser_list().get(0).getUser_info();
                String Token = JWTUtil.createToken(jwtId, userId, username);
                Map<String,String> res = new HashMap<>();
                res.put("Token",Token);
                res.put("userId",userId);
                res.put("username",username);
                return ResultBody.ok().message("识别成功").data("userInfo", res);
            }
            return ResultBody.error().message("识别失败，匹配不到你的信息");
        }catch (Exception e){
            throw new BusinessException(ResultEnum.NOT_VALID);
        }
    }


    @GetMapping("/getCode")
    public ResultBody getCodes() {
        FaceVedioBean faceUserBean = FaceH5Check.getCode(DBFactory.getAipFace());
        return ResultBody.ok().data("code", faceUserBean.getResult().getCode()).data("uuid", faceUserBean.getUuid());
    }


    //通过视频登陆
    @PostMapping("/faceVideoCheck")
    public ResultBody faceTest(@RequestParam("uuid") String uuid, @RequestParam("videoFile") MultipartFile videoFile) throws IOException {
        String newFileName = UploadUtil.upload(videoFile);
        String SessionId = RedisUtil.get(uuid).toString();
        String json = FaceH5Check.uploadH5Video(DBFactory.getAipFace(), newFileName, SessionId);
        System.out.println(json);
        int err_no = Integer.parseInt(JSONUtil.getJsonValueBykey(json, "err_no").toString());
        System.out.println("err_no:"+err_no);
        System.out.println(err_no==0);
        if (err_no == 216502) {
            return ResultBody.error().message("sessionId已失效，请获取语音码并重试");
        }
        if(err_no == 216509) {
            return ResultBody.error().message("声音过小或杂音太大无法识别，或者为非视频格式，请获取语音码重试");
        }
        if (err_no == 0) {
            RedisUtil.del(uuid);
            System.out.println("err_no==0，视频上传成功");
            FaceH5Bean faceH5Bean = new Gson().fromJson(json, FaceH5Bean.class);
            double score = faceH5Bean.getResult().getScore();
            double similarity = faceH5Bean.getResult().getCode().getSimilarity();
            String faceToken = faceH5Bean.getResult().getBest_image().getFace_token();
            //活体认证率大于0.8，并且数字正确率大于0.8
            if (score>=0.8&&similarity>=0.8){
                String faceJsons = FaceOperate.faceSearchByImgToken(faceToken, "user");
                FaceResultBean faceJson = new Gson().fromJson(faceJsons, FaceResultBean.class);
                int faceCode = faceJson.getError_code();
                if (faceCode == 223120) {
                    System.out.println("无法识别");
                    return ResultBody.error().message("无法识别");
                }
                double faceScore = faceJson.getResult().getUser_list().get(0).getScore();
                if (faceScore >= 80) {
                    System.out.println("人脸识别成功");
                    String jwtId = UUID.randomUUID().toString();
                    String userId = faceJson.getResult().getUser_list().get(0).getUser_id();
                    String username = faceJson.getResult().getUser_list().get(0).getUser_info();
                    String Token = JWTUtil.createToken(jwtId, userId, username);
                    return ResultBody.ok().message("识别成功").data("Token", Token);
                }
                System.out.println("识别失败");
                return ResultBody.error().message("识别失败，匹配不到你的信息");
            }else{
                return ResultBody.error().message("活体认证失败,请重新获取code并重试");
            }
        }
        return ResultBody.error().message("到达使用上限");
    }
}
